package com.ma.chapter5.t1;

import lombok.extern.slf4j.Slf4j;

import static com.ma.util.Sleeper.sleep;

/**
 * @ClassName TestVisibility
 * @Author: mayongqiang
 * @DATE 2022/3/17 0:24
 * @Description: 可见性:退不出的循环
 */
@Slf4j(topic = "m.TestVisibility")
public class TestVisibility {
    /*
    1.对于可见性，Java提供了volatile关键字来保证可见性。当一个共享变量被volatile修饰时，
            它会保证修改的值会立即被更新到主存，当有其他线程需要读取时，它会去内存中读取新值。
    2. 同时通过synchronized和Lock也能够保证可见性，synchronized和Lock能保证同一时刻
            只有一个线程获取锁然后执行同步代码，并且在释放锁之前会将对变量的修改刷新到主存当中。因此可以保证可见性。
     */

    //锁对象
    final static Object lock = new Object();
    static boolean run = true;


    public static void main(String[] args) {
        /* 循环多次，run 值被JIT缓存到高速缓存这个
            volatile（易变关键字）
                它可以用来修饰成员变量和静态成员变量，他可以避免线程从自己的工作缓存中查找变量的值，必须到主存中获取
                它的值，线程操作 volatile 变量都是直接操作主存
         */
        Thread t = new Thread(() -> {
            while (true) {
                synchronized (lock) {
                    if (!run) {
                        break;
                    }
                    //...
                }

            }
        });
        t.start();
        sleep(1);
        log.debug("stop t");
        synchronized (lock) {
            run = false;
        }
    }
}
